package com.clp.protocol.core.utils;

import cn.hutool.core.lang.Validator;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.*;
import java.util.stream.Collectors;

public class IpUtil {
    private IpUtil() {}

    private static final List<InetAddress> inetAddresses;
    private static final Set<String> localIpSet;

    static {
        inetAddresses = initInetAddresses();
        localIpSet = initLocalIpSet();
    }

    private static List<InetAddress> initInetAddresses() {
        List<InetAddress> list = new ArrayList<>();
        try {
            //get all network interface
            Enumeration<NetworkInterface> allNetworkInterfaces = NetworkInterface.getNetworkInterfaces();

            NetworkInterface networkInterface = null;
            //check if there are more than one network interface
            while (allNetworkInterfaces.hasMoreElements()) {
                //get next network interface
                networkInterface = allNetworkInterfaces.nextElement();
                if (networkInterface.isVirtual() || !networkInterface.isUp() || networkInterface.isLoopback()) {
                    continue;
                }
                //output interface's name
//                System.out.println("network interface: " +
//                        networkInterface.getDisplayName());

                //get all ip address that bound to this network interface
                Enumeration<InetAddress> allInetAddress = networkInterface.getInetAddresses();

                InetAddress ipAddress = null;
                //check if there are more than one ip addresses
                //band to one network interface
                while (allInetAddress.hasMoreElements()) {
                    //get next ip address
                    ipAddress = allInetAddress.nextElement();
                    if (ipAddress != null && ipAddress instanceof Inet4Address) {
//                        System.out.println("ip address: " + ipAddress.getHostAddress());
                        list.add(ipAddress);
                    }
                }
            }

        } catch (SocketException e) {
            e.printStackTrace();
        }
        return list;
    }

    public static List<InetAddress> getInetAddresses() {
        return inetAddresses;
    }

    private static Set<String> initLocalIpSet() {
        return Collections.unmodifiableSet(getInetAddresses().stream().map(InetAddress::getHostAddress).collect(Collectors.toSet()));
    }

    public static Set<String> getLocalIpSet() {
        return localIpSet;
    }

    /**
     * 检查本机是否存在该ip
     * @param localHost
     */
    public static boolean hasLocalHost(String localHost) {
        return localIpSet.contains(localHost);
    }

    public static boolean isIpv4(String ip) {
        return Validator.isIpv4(ip);
    }
}
